package com.wrupple.muba.catalogs.client.activity.process.state.impl;

import java.util.ArrayList;
import java.util.List;

import com.google.inject.Provider;
import com.wrupple.muba.catalogs.domain.CatalogProcessDescriptor;
import com.wrupple.muba.common.domain.FilterCriteria;
import com.wrupple.muba.common.domain.FilterData;
import com.wrupple.muba.common.shared.Process;

public abstract class AbstractCatalogProcessFilterLoadingState<T>
		extends
		AbstractCatalogProcessDescriptorLoadingState<CatalogProcessDescriptor, List<T>> {

	private String affectedFilterableField;
	private String selectionCatalogType;
	private String filterOperator;

	public AbstractCatalogProcessFilterLoadingState(
			Provider<? extends Process<CatalogProcessDescriptor, List<T>>> provider,String selectionCatalogType,
			String affectedFilterableField) {
		super(provider);
		this.affectedFilterableField = affectedFilterableField;
		this.selectionCatalogType = selectionCatalogType;
	}

	@Override
	protected void setValue(CatalogProcessDescriptor parameter, List<T> result) {
		FilterData fdata = parameter.getFilterData();
		if (fdata == null) {
			fdata = new FilterData();
		}
		fdata.getFilters().put(affectedFilterableField,
				generateFilterCriteriaFromSelectedValues(result));
	}
	
	@Override
	protected CatalogProcessDescriptor generateWrappedProcessInput() {
		CatalogProcessDescriptor regreso = new CatalogProcessDescriptor();
		regreso.setSelectedType(selectionCatalogType);
		return regreso;
	}

	protected List<FilterCriteria> generateFilterCriteriaFromSelectedValues(
			List<T> values) {
		if(values==null||values.isEmpty()){
			return null;
		}else{
			List<FilterCriteria> regreso = new ArrayList<FilterCriteria>(values.size());
			
			FilterCriteria temp = new FilterCriteria();
			temp.setOperator(filterOperator);
			temp.setValues(extractFilterableValues(values));
			regreso.add(temp);
			return regreso;
		}
		
	}

	private List<String> extractFilterableValues(List<T> values) {
		List<String> regreso = new ArrayList<String>(values.size());
		
		for(T value:values){
			String filterableValue= extractFilterableValue(value);
			regreso.add(filterableValue);
		}
		
		return regreso;
	}
	
	@Override
	protected boolean testCurrentState(CatalogProcessDescriptor parameter) {
		return !parameter.getFilterData().getFilters().containsKey(this.affectedFilterableField);
	}

	protected abstract String extractFilterableValue(T value);

}
